package com.pethome.web.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pethome.common.constant.CacheConstants;
import com.pethome.common.constant.Constants;
import com.pethome.common.constant.UserConstants;
import com.pethome.common.core.domain.entity.Customer;
import com.pethome.common.core.domain.model.LoginUser;
import com.pethome.common.core.domain.model.RegisterBody;
import com.pethome.common.core.redis.RedisCache;
import com.pethome.common.enums.UserStatus;
import com.pethome.common.exception.ServiceException;
import com.pethome.common.exception.user.CaptchaException;
import com.pethome.common.exception.user.CaptchaExpireException;
import com.pethome.common.utils.MessageUtils;
import com.pethome.common.utils.SecurityUtils;
import com.pethome.common.utils.StringUtils;
import com.pethome.framework.manager.AsyncManager;
import com.pethome.framework.manager.factory.AsyncFactory;
import com.pethome.framework.security.context.AuthenticationContextHolder;
import com.pethome.framework.web.service.TokenService;
import com.pethome.system.service.ISysConfigService;
import com.pethome.web.mapper.CustomerMapper;
import com.pethome.web.service.ICustomerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 客户信息Service业务层处理
 * 
 * @author hjc
 * @date 2024-08-25
 */
@Slf4j
@Service
public class CustomerServiceImpl  extends ServiceImpl<CustomerMapper,Customer> implements ICustomerService
        {
    @Resource
    private CustomerMapper customerMapper;
            @Resource
            private TokenService tokenService;

            @Autowired
            private ISysConfigService configService;

            @Autowired
            private RedisCache redisCache;



            /**
             *  登录
             * @param username
             * @param password
             * @param code
             * @param uuid
             * @return
             */
            @Override
            public Map<String ,Object> login(String username, String password, String code, String uuid) {

//验证码
                validateCaptcha(username, code, uuid);


                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
                AuthenticationContextHolder.setContext(authenticationToken);

                QueryWrapper<Customer>  qw = new QueryWrapper<Customer>();
                qw.eq("customer_name",username);
                Customer user = this.getOne(qw);

                if (StringUtils.isNull(user))
                {
                    log.info("登录用户：{} 不存在.", username);
                    throw new ServiceException(MessageUtils.message("用户不存在"));
                }
                else if (UserStatus.DISABLE.getCode().equals(user.getCustomerStatus().toString()))
                {
                    log.info("登录用户：{} 已被删除.", username);
                    throw new ServiceException(MessageUtils.message("用户已被删除，请联系管理员"));
                }
                else if (UserStatus.DELETED.getCode().equals(user.getCustomerStatus().toString()))
                {
                    log.info("登录用户：{} 已被拉黑.", username);
                    throw new ServiceException(MessageUtils.message("用户已被拉黑，请联系管理员"));
                }
                log.info(user.getCustomerName());
                log.warn(":"+ SecurityUtils.encryptPassword("123456"));

                //判断密码                         真实密码       加密后的密码
                if(!SecurityUtils.matchesPassword(password,user.getCustomerPwd())){
                    log.info("密码不正确");
                    throw new ServiceException(MessageUtils.message("密码错误"));
                }
                HashMap<String,Object> map = new HashMap<String ,Object>();
                String token=  tokenService.createToken(new LoginUser(Long.valueOf(user.getCustomerId()),user));
                log.warn(token);
                AuthenticationContextHolder.clearContext();

              AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
               map.put("token",token);
               map.put("customerId",user.getCustomerId());
                map.put("customerName",user.getCustomerName());
                map.put("customerAvatar",user.getCustomerAvatar());

                return map;
            }


            public String register(RegisterBody registerBody)
            {
                log.info(registerBody.getUsername());
                String msg = "", username = registerBody.getUsername(), password = registerBody.getPassword();
                Customer customer = new Customer();

                log.warn("验证码");
                // 验证码开关
                boolean captchaEnabled = configService.selectCaptchaEnabled();
                if (captchaEnabled)
                {
                    validateCaptcha(username, registerBody.getCode(), registerBody.getUuid());
                }
                log.warn("格式判断");
                if (StringUtils.isEmpty(username))
                {
                    msg = "用户名不能为空";
                }
                else if (StringUtils.isEmpty(password))
                {
                    msg = "用户密码不能为空";
                }
                else if (username.length() < UserConstants.USERNAME_MIN_LENGTH
                        || username.length() > UserConstants.USERNAME_MAX_LENGTH)
                {
                    msg = "账户长度必须在2到20个字符之间";
                }
                else if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
                        || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
                {
                    msg = "密码长度必须在5到20个字符之间";
                }
                else if (customerMapper.selectCustomerByCustomerName(username)!=null)
                {
                    msg = "保存用户'" + username + "'失败，注册账号已存在";
                    log.warn(msg);
                }
                else
                {
                    customer.setCustomerName(username);
                    customer.setCustomerPwd(SecurityUtils.encryptPassword(password));
                    customer.setCustomerPhone(registerBody.getPhone());
                    log.warn(customer.toString());
                    Customer customer1=this.getBaseMapper().selectCustomerByCustomerName(username);
                    log.info(String.valueOf(customer1==null));
                    if (customer1!=null)
                    {
                        msg = "注册失败,请联系系统管理人员";
                    }
                    else
                    {
                        this.save(customer);
//                使用某种异步处理机制来记录用户注册成功的日志信息
                        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.register.success")));
                    }
                }
                return msg;
            }

            /**
             * 校验验证码
             *
             * @param username 用户名
             * @param code 验证码
             * @param uuid 唯一标识
             * @return 结果
             */
            public void validateCaptcha(String username, String code, String uuid)
            {
                String verifyKey2 = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
                String captcha = redisCache.getCacheObject(verifyKey2);
                redisCache.deleteObject(verifyKey2);
                if (captcha == null)
                {
                    throw new CaptchaExpireException();
                }
                if (!code.equalsIgnoreCase(captcha))
                {
                    throw new CaptchaException();
                }
            }























            /**
     * 查询客户信息
     * 
     * @param customerId 客户信息主键
     * @return 客户信息
     */
    @Override
    public Customer selectCustomerByCustomerId(Long customerId)
    {
        Customer customer = customerMapper.selectCustomerByCustomerId(customerId);
        return customer;
    }

    /**
     * 查询客户信息列表
     * 
     * @param customer 客户信息
     * @return 客户信息
     */
    @Override
    public List<Customer> selectCustomerList(Customer customer)
    {
        return customerMapper.selectCustomerList(customer);
    }

    /**
     * 新增客户信息
     * 
     * @param customer 客户信息
     * @return 结果
     */
    @Override
    public int insertCustomer(Customer customer)
    {
        return customerMapper.insertCustomer(customer);
    }

    /**
     * 修改客户信息
     * 
     * @param customer 客户信息
     * @return 结果
     */
    @Override
    public int updateCustomer(Customer customer)
    {
        return customerMapper.updateCustomer(customer);
    }

    /**
     * 批量删除客户信息
     * 
     * @param customerIds 需要删除的客户信息主键
     * @return 结果
     */
    @Override
    public int deleteCustomerByCustomerIds(Long[] customerIds)
    {
        return customerMapper.deleteCustomerByCustomerIds(customerIds);
    }

    /**
     * 删除客户信息信息
     * 
     * @param customerId 客户信息主键
     * @return 结果
     */
    @Override
    public int deleteCustomerByCustomerId(Long customerId)
    {
        return customerMapper.deleteCustomerByCustomerId(customerId);
    }

    /**
     * 恢复客户信息信息
     *
     * @param customerId 客户信息主键
     * @return 结果
     */
    @Override
    public int reCustomer(Long customerId)
    {

        return customerMapper.reCustomer(customerId);
    }
    /**
     * 拉黑客户信息信息
     *
     * @param customerId 客户信息主键
     * @return 结果
     */
    @Override
    public int LaHeiCustomer(Long customerId)
    {

        return customerMapper.LaHeiCustomer(customerId);
    }
}
